package cn.ronghuanet.basic.service.impl;

import cn.ronghuanet.basic.service.IVerifyCodeService;
import cn.ronghuanet.basic.util.AjaxResult;
import cn.ronghuanet.basic.util.SendSMSUtils;
import cn.ronghuanet.basic.util.StrUtils;
import cn.ronghuanet.basic.util.VerifyCodeUtils;
import cn.ronghuanet.user.domain.Logininfo;
import cn.ronghuanet.user.domain.User;
import cn.ronghuanet.user.mapper.LogininfoMapper;
import cn.ronghuanet.user.mapper.UserMapper;
import org.apache.commons.httpclient.Header;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.NameValuePair;
import org.apache.commons.httpclient.methods.PostMethod;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

@Service
public class VerifyCodeServiceImpl implements IVerifyCodeService {
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private LogininfoMapper logininfoMapper;

    @Autowired
    private UserMapper userMapper;

    @Override
    public String getImageCode(String imageCodeKey) throws IOException {
        // 通过工具类生成验证码
        String complexRandomString = StrUtils.getComplexRandomString(6);
        // 存redis
        redisTemplate.opsForValue().set(imageCodeKey,complexRandomString);
        // 设置图形验证码的过期时间
        redisTemplate.expire(imageCodeKey,5,TimeUnit.MINUTES);
        // 生成base64内容
        return VerifyCodeUtils.VerifyCode(120,30,complexRandomString);
    }

    // 获取短信验证码的方法
    @Override
    public AjaxResult sendSmsCode(Map<String, String> map) {
        AjaxResult ajaxResult = new AjaxResult();
        // 1. 取值
        String phone = map.get("mobile");
        String imageCode = map.get("imageCode");
        String imageCodeKey = map.get("imageCodeKey");
        // 2. 校验 -> 空值校验
        if (Objects.isNull(phone)
                || Objects.isNull(imageCode)
                || Objects.isNull(imageCodeKey)
        ){
            return ajaxResult.setSuccess(false).setMessage("参数不正确");
        }
        // 3. 图形验证码是否正确
        Object imageCodeRedis = redisTemplate.opsForValue().get(imageCodeKey);
        if (Objects.isNull(imageCode)){
            return ajaxResult.setSuccess(false).setMessage("图形验证码不存在");
        }
        if (!imageCode.equals((String) imageCodeRedis)){
            return ajaxResult.setSuccess(false).setMessage("图形验证码不正确");
        }
        // 4. 手机号是否已经注册
        Logininfo logininfo = logininfoMapper.queryByPhone(phone);
        if (Objects.nonNull(logininfo)){
            return ajaxResult.setSuccess(false).setMessage("用户已注册请登录");
        }
        // 5. 生成手机验证码
        String randomString = StrUtils.getRandomString(6);
        // 5.1 判断redis中是否有该手机验证码 没有 就生成新的发送
        Map<String,Object> entries = redisTemplate.opsForHash().entries("reg_" + phone);
         // redisTemplate.opsForValue().set("手机号"，"验证码.时间");
        if (Objects.isNull(entries) || entries.size() == 0){
            HashMap<String, Object> map1 = new HashMap<>();
            map1.put("smsCode",randomString);
            map1.put("sendMilis",new Date().getTime());// 为了计算是否已经发出去一分钟
            // 存入redis
            redisTemplate.opsForHash().putAll("reg_" + phone,map1);
            redisTemplate.expire("reg_" + phone,5, TimeUnit.MINUTES);
        }else{
            // 5.2 如果有验证码 -> 获取 发送旧的验证码 重置过期时间
            // 第一次发送的时间
            Long sendMilis = (Long)entries.get("sendMilis");
            // 和当前时间相比如果没有超过一分钟就不在重新发送
            //如果有验证码 但是验证码还没有超过一分钟
            if ((new Date().getTime() - sendMilis)<=60*1000){
                return ajaxResult.setSuccess(false).setMessage("操作太频繁,请稍后在试");
            }
            String smsCode = (String)entries.get("smsCode");
            // 发送短信
            // 更新redis的过期时间
            redisTemplate.expire("reg_" + phone,5, TimeUnit.MINUTES);
        }
        SendSMSUtils.senSMS(phone,randomString);
        return ajaxResult;
    }

    // 绑定界面的验证码
    @Override
    public AjaxResult smsbind(Map<String, String> map) {
        AjaxResult ajaxResult = new AjaxResult();
         String phone = map.get("mobile");
        // 5. 生成手机验证码
        String randomString = StrUtils.getRandomString(6);
        // 5.1 判断redis中是否有该手机验证码 没有 就生成新的发送
        Map<String,Object> entries = redisTemplate.opsForHash().entries("bind_" + phone);
        // redisTemplate.opsForValue().set("手机号"，"验证码.时间");
        if (Objects.isNull(entries) || entries.size() == 0){
            HashMap<String, Object> map1 = new HashMap<>();
            map1.put("smsCode",randomString);
            map1.put("sendMilis",new Date().getTime());// 为了计算是否已经发出去一分钟
            // 存入redis
            redisTemplate.opsForHash().putAll("bind_" + phone,map1);
            redisTemplate.expire("bind_" + phone,5, TimeUnit.MINUTES);
        }else{
            // 5.2 如果有验证码 -> 获取 发送旧的验证码 重置过期时间
            // 第一次发送的时间
            Long sendMilis = (Long)entries.get("sendMilis");
            // 和当前时间相比如果没有超过一分钟就不在重新发送
            //如果有验证码 但是验证码还没有超过一分钟
            if ((new Date().getTime() - sendMilis)<=60*1000){
                return ajaxResult.setSuccess(false).setMessage("操作太频繁,请稍后在试");
            }
            String smsCode = (String)entries.get("smsCode");
            // 发送短信
            // 更新redis的过期时间
            redisTemplate.expire("bind_" + phone,5, TimeUnit.MINUTES);
        }
//        SendSMSUtils.senSMS(phone,randomString);
        return ajaxResult;
    }


}
